import { Injectable, Logger, BadRequestException } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { Repository, DataSource } from "typeorm";
import { FactionEntity } from "../entities/faction.entity";
import { FactionMemberEntity } from "../entities/faction-member.entity";
import { CharacterEntity } from "../entities/character.entity";

@Injectable()
export class FactionService {
  private readonly logger = new Logger(FactionService.name);

  // 帮派类型映射
  private readonly factionTypes: Record<number, string> = {
    1: "派",
    2: "教",
    3: "会",
    4: "帮",
    5: "楼",
    6: "阁",
    7: "军",
    8: "组",
    9: "社",
    10: "族",
  };

  // 成员角色映射
  private readonly memberRoles: Record<number, string> = {
    0: "不是成员",
    1: "准成员",
    2: "成员",
    3: "管理",
    4: "帮主",
  };

  constructor(
    @InjectRepository(FactionEntity)
    private readonly factionRepository: Repository<FactionEntity>,
    @InjectRepository(FactionMemberEntity)
    private readonly factionMemberRepository: Repository<FactionMemberEntity>,
    @InjectRepository(CharacterEntity)
    private readonly characterRepository: Repository<CharacterEntity>,
    private readonly dataSource: DataSource
  ) {}

  /**
   * 创建帮派
   */
  async createFaction(
    characterId: number,
    type: number,
    name: string,
    description: string
  ): Promise<FactionEntity> {
    const queryRunner = this.dataSource.createQueryRunner();
    await queryRunner.connect();
    await queryRunner.startTransaction();

    try {
      // 检查角色是否已有帮派
      const existingMember = await queryRunner.manager.findOne(
        FactionMemberEntity,
        {
          where: { characterId, status: 1 },
        }
      );

      if (existingMember) {
        throw new BadRequestException("您已经加入其他帮派");
      }

      // 检查帮派名称是否已存在
      const existingFaction = await queryRunner.manager.findOne(FactionEntity, {
        where: { name, status: 1 },
      });

      if (existingFaction) {
        throw new BadRequestException("帮派名称已存在");
      }

      // 获取角色信息
      const character = await queryRunner.manager.findOne(CharacterEntity, {
        where: { id: characterId },
      });

      if (!character) {
        throw new BadRequestException("角色不存在");
      }

      // 创建帮派
      const faction = queryRunner.manager.create(FactionEntity, {
        name,
        description,
        type,
        leaderId: characterId,
        announcement: description,
        memberCount: 1,
        maxMembers: 50,
        level: 1,
        exp: 0,
        funds: 0,
        minLevel: 0,
        resistance: "抗物理 20%,抗玄击 10%",
        status: 1,
      });

      const savedFaction = await queryRunner.manager.save(faction);

      // 创建帮主成员记录
      const leaderMember = queryRunner.manager.create(FactionMemberEntity, {
        factionId: savedFaction.id,
        characterId,
        role: 4, // 帮主
        contribution: 0,
        status: 1,
      });

      await queryRunner.manager.save(leaderMember);

      await queryRunner.commitTransaction();

      this.logger.log(`帮派创建成功: ${name} (ID: ${savedFaction.id})`);
      return savedFaction;
    } catch (error) {
      await queryRunner.rollbackTransaction();
      this.logger.error(`创建帮派失败:`, error);
      throw error;
    } finally {
      await queryRunner.release();
    }
  }

  /**
   * 获取帮派信息
   */
  async getFactionInfo(characterId: number): Promise<any> {
    try {
      // 查找角色所属帮派
      const member = await this.factionMemberRepository.findOne({
        where: { characterId, status: 1 },
        relations: ["faction", "faction.leader"],
      });

      if (!member) {
        return null;
      }

      const faction = member.faction;
      const leader = faction.leader;

      return {
        id: faction.id,
        name: faction.name,
        notice: faction.announcement || faction.description,
        lead: leader?.name || "未知",
        lvl: faction.level,
        mem: faction.memberCount,
        maxSum: faction.maxMembers,
        money: faction.funds,
        minLvl: faction.minLevel,
        kang: faction.resistance || "抗物理 20%,抗玄击 10%",
        credit: 0, // 暂时写死
        k1: 0, // 暂时写死
        k2: 0, // 暂时写死
        one: 0, // 暂时写死
        two: 0, // 暂时写死
        three: 0, // 暂时写死
        present: 0, // 暂时写死
        q: 0, // 暂时写死
        sum: faction.memberCount,
      };
    } catch (error) {
      this.logger.error(`获取帮派信息失败:`, error);
      throw error;
    }
  }

  /**
   * 获取帮派成员列表
   */
  async getFactionMembers(
    factionId: number,
    pageNum: number = 0,
    pageSize: number = 20
  ): Promise<{
    list: any[];
    more: string;
  }> {
    try {
      const faction = await this.factionRepository.findOne({
        where: { id: factionId, status: 1 },
      });

      if (!faction) {
        throw new BadRequestException("帮派不存在");
      }

      const [members, total] = await this.factionMemberRepository.findAndCount({
        where: { factionId, status: 1 },
        relations: ["character"],
        skip: pageNum * pageSize,
        take: pageSize,
        order: { role: "DESC", joinDate: "ASC" },
      });

      const list = members.map((member) => ({
        id: member.characterId,
        n: member.character?.name || "未知",
        o: member.role,
        t: this.memberRoles[member.role] || "未知",
      }));

      return {
        list,
        more: faction.name,
      };
    } catch (error) {
      this.logger.error(`获取帮派成员列表失败:`, error);
      throw error;
    }
  }

  /**
   * 解散帮派
   */
  async disbandFaction(characterId: number): Promise<void> {
    const queryRunner = this.dataSource.createQueryRunner();
    await queryRunner.connect();
    await queryRunner.startTransaction();

    try {
      // 查找帮派
      const faction = await queryRunner.manager.findOne(FactionEntity, {
        where: { leaderId: characterId, status: 1 },
      });

      if (!faction) {
        throw new BadRequestException("您不是帮主或帮派不存在");
      }

      // 更新帮派状态为解散
      await queryRunner.manager.update(
        FactionEntity,
        { id: faction.id },
        { status: 0 }
      );

      // 更新所有成员状态
      await queryRunner.manager.update(
        FactionMemberEntity,
        { factionId: faction.id },
        { status: 0 }
      );

      await queryRunner.commitTransaction();

      this.logger.log(`帮派解散成功: ${faction.name} (ID: ${faction.id})`);
    } catch (error) {
      await queryRunner.rollbackTransaction();
      this.logger.error(`解散帮派失败:`, error);
      throw error;
    } finally {
      await queryRunner.release();
    }
  }

  /**
   * 申请加入帮派
   */
  async applyToJoinFaction(
    characterId: number,
    factionId: number,
    type: number
  ): Promise<void> {
    try {
      // 检查帮派是否存在
      const faction = await this.factionRepository.findOne({
        where: { id: factionId, status: 1 },
      });

      if (!faction) {
        throw new BadRequestException("帮派不存在");
      }

      // 检查是否已经是成员
      const existingMember = await this.factionMemberRepository.findOne({
        where: { characterId, factionId, status: 1 },
      });

      if (existingMember) {
        throw new BadRequestException("您已经是该帮派成员");
      }

      // 检查帮派是否已满
      if (faction.memberCount >= faction.maxMembers) {
        throw new BadRequestException("帮派成员已满");
      }

      // 创建申请记录（这里简化为直接加入，实际应该有申请-审批流程）
      const member = this.factionMemberRepository.create({
        factionId,
        characterId,
        role: 1, // 准成员
        contribution: 0,
        status: 1,
      });

      await this.factionMemberRepository.save(member);

      // 更新帮派成员数量
      await this.factionRepository.update(
        { id: factionId },
        { memberCount: faction.memberCount + 1 }
      );

      this.logger.log(`角色 ${characterId} 申请加入帮派 ${faction.name} 成功`);
    } catch (error) {
      this.logger.error(`申请加入帮派失败:`, error);
      throw error;
    }
  }

  /**
   * 获取帮派类型名称
   */
  getFactionTypeName(type: number): string {
    return this.factionTypes[type] || "未知";
  }

  /**
   * 获取成员角色名称
   */
  getMemberRoleName(role: number): string {
    return this.memberRoles[role] || "未知";
  }

  /**
   * 获取帮派列表
   */
  async getFactionList(
    type: number = 3,
    pageNum: number = 0,
    pageSize: number = 20
  ): Promise<{
    list: any[];
    page: number;
    sum: number;
  }> {
    try {
      // 构建查询条件
      const whereCondition: any = { status: 1 };

      // 如果指定了帮派类型，则按类型筛选
      if (type && type > 0) {
        whereCondition.type = type;
      }

      // 计算分页
      const skip = pageNum * pageSize;

      // 根据type确定排序字段
      let orderBy: any = {};
      let valField: string;

      if (type === 1) {
        // type=1: 按帮派人数排名
        orderBy = {
          memberCount: "DESC", // 按成员数量降序排列
          id: "ASC", // 人数相同时按ID升序
        };
        valField = "memberCount";
      } else {
        // type=3或其他: 按经验值排名
        orderBy = {
          exp: "DESC", // 按经验值降序排列
          id: "ASC", // 经验相同时按ID升序
        };
        valField = "exp";
      }

      // 查询帮派列表，包含帮主信息
      const [factions, total] = await this.factionRepository.findAndCount({
        where: whereCondition,
        relations: ["leader"],
        order: orderBy,
        skip,
        take: pageSize,
      });

      // 格式化返回数据
      const list = factions.map((faction, index) => ({
        id: faction.id,
        master: faction.leader?.name || "未知",
        name: faction.name,
        num: skip + index + 1, // 排名
        val: valField === "memberCount" ? faction.memberCount : faction.exp, // 根据type使用不同的排序依据
      }));

      return {
        list,
        page: pageNum + 1,
        sum: total,
      };
    } catch (error) {
      this.logger.error(`获取帮派列表失败:`, error);
      throw error;
    }
  }
}
